home *** CD-ROM | disk | FTP | other *** search
- /* SampleStorageActual.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "SampleStorageActual.h"
- #include "Memory.h"
-
-
- /* data is stored in the following format: */
- /* - 8bit mono: packed array of bytes */
- /* - 16bit mono: packed array of short integers */
- /* - 8bit stereo: packed array of 2-byte units, the lower == left channel */
- /* - 16bit stereo: packed array of 2-short int units, the lower == left channel */
-
-
- struct SampleStorageActualRec
- {
- char* Buffer;
- NumBitsType NumberOfBits;
- NumChannelsType MonoStereo;
- long NumFrames;
- };
-
-
- /* create a new sample storage object, with the array zeroed out */
- SampleStorageActualRec* NewSampleStorageActual(NumBitsType NumBits,
- NumChannelsType NumChannels, long NumSampleFrames)
- {
- SampleStorageActualRec* Storage;
- long BytesPerFrame;
- long Limit;
- long Scan;
-
- ERROR((NumBits != eSample8bit) && (NumBits != eSample16bit),PRERR(ForceAbort,
- "eSampleStereo: bad number of bits"));
- ERROR((NumChannels != eSampleMono) && (NumChannels != eSampleStereo),
- PRERR(ForceAbort,"eSampleStereo: bad number of channels"));
- Storage = (SampleStorageActualRec*)AllocPtrCanFail(sizeof(SampleStorageActualRec),
- "SampleStorageActualRec");
- if (Storage == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- BytesPerFrame = 1;
- switch (NumBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewSampleStorageActual: bad num bits"));
- break;
- case eSample8bit:
- break;
- case eSample16bit:
- BytesPerFrame = BytesPerFrame * (sizeof(short) / sizeof(char));
- break;
- }
- switch (NumChannels)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"NewSampleStorageActual: bad num channels"));
- break;
- case eSampleMono:
- break;
- case eSampleStereo:
- BytesPerFrame = BytesPerFrame * 2;
- break;
- }
- Storage->Buffer = AllocPtrCanFail((NumSampleFrames + 1) * BytesPerFrame,
- "SampleArray");
- if (Storage->Buffer == NIL)
- {
- FailurePoint2:
- ReleasePtr((char*)Storage);
- goto FailurePoint1;
- }
- Limit = PtrSize(Storage->Buffer);
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- Storage->Buffer[Scan] = 0;
- }
- Storage->NumberOfBits = NumBits;
- Storage->MonoStereo = NumChannels;
- Storage->NumFrames = NumSampleFrames;
- return Storage;
- }
-
-
- /* dispose of a sample storage object */
- void DisposeSampleStorageActual(SampleStorageActualRec* Storage)
- {
- CheckPtrExistence(Storage);
- ReleasePtr(Storage->Buffer);
- ReleasePtr((char*)Storage);
- }
-
-
- /* get the number of bits the sample storage object contains */
- NumBitsType GetSampleStorageActualNumBits(SampleStorageActualRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->NumberOfBits;
- }
-
-
- /* get the number of channels the storage object contains */
- NumChannelsType GetSampleStorageActualNumChannels(
- SampleStorageActualRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->MonoStereo;
- }
-
-
- /* get the number of sample frames the object contains */
- long GetSampleStorageActualNumFrames(
- SampleStorageActualRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->NumFrames;
- }
-
-
- /* get the value of a sample frame */
- largefixedsigned GetSampleStorageActualValue(SampleStorageActualRec* Storage,
- long Index, ChannelType WhichChannel)
- {
- double Resultant;
-
- CheckPtrExistence(Storage);
- switch (Storage->MonoStereo)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageActualValue: bad internal num channels"));
- break;
- case eSampleMono:
- ERROR(WhichChannel != eMonoChannel,PRERR(ForceAbort,
- "GetSampleStorageActualValue: invalid channel selector"));
- switch (Storage->NumberOfBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageActualValue: bad internal num bits"));
- break;
- case eSample8bit:
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[Index]),
- sizeof(char));
- Resultant = ((double)((signed char*)Storage->Buffer)[Index]) / MAX8BIT;
- break;
- case eSample16bit:
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[Index]),
- sizeof(short));
- Resultant = ((double)((signed short*)Storage->Buffer)[Index]) / MAX16BIT;
- break;
- }
- break;
- case eSampleStereo:
- switch (Storage->NumberOfBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageActualValue: bad internal num bits"));
- break;
- case eSample8bit:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageActualValue: bad channel selector"));
- break;
- case eLeftChannel:
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[2 * Index]),
- sizeof(char));
- Resultant = ((double)((signed char*)Storage->Buffer)[2 * Index])
- / MAX8BIT;
- break;
- case eRightChannel:
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
- [(2 * Index) + 1]),sizeof(char));
- Resultant = ((double)((signed char*)Storage->Buffer)[(2 * Index) + 1])
- / MAX8BIT;
- break;
- }
- break;
- case eSample16bit:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "GetSampleStorageActualValue: bad channel selector"));
- break;
- case eLeftChannel:
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[2 * Index]),
- sizeof(short));
- Resultant = ((double)((signed short*)Storage->Buffer)[2 * Index])
- / MAX8BIT;
- break;
- case eRightChannel:
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
- [(2 * Index) + 1]),sizeof(short));
- Resultant = ((double)((signed short*)Storage->Buffer)[(2 * Index) + 1])
- / MAX8BIT;
- break;
- }
- break;
- }
- break;
- }
- return double2largefixed(Resultant);
- }
-
-
- /* change the value of a sample frame */
- void SetSampleStorageActualValue(SampleStorageActualRec* Storage,
- long Index, ChannelType WhichChannel,
- largefixedsigned NewValue)
- {
- double TargetValue;
-
- CheckPtrExistence(Storage);
- switch (Storage->MonoStereo)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "SetSampleStorageActualValue: bad internal num channels"));
- break;
- case eSampleMono:
- ERROR(WhichChannel != eMonoChannel,PRERR(ForceAbort,
- "SetSampleStorageActualValue: invalid channel selector"));
- switch (Storage->NumberOfBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "SetSampleStorageActualValue: bad internal num bits"));
- break;
- case eSample8bit:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
- if (TargetValue > MAX8BIT)
- {
- TargetValue = MAX8BIT;
- }
- else if (TargetValue < MIN8BIT)
- {
- TargetValue = MIN8BIT;
- }
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[Index]),
- sizeof(char));
- ((char*)Storage->Buffer)[Index] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
- [Storage->NumFrames]),sizeof(char));
- ((char*)Storage->Buffer)[Storage->NumFrames] = TargetValue;
- }
- break;
- case eSample16bit:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
- if (TargetValue > MAX16BIT)
- {
- TargetValue = MAX16BIT;
- }
- else if (TargetValue < MIN16BIT)
- {
- TargetValue = MIN16BIT;
- }
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[Index]),
- sizeof(short));
- ((short*)Storage->Buffer)[Index] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
- [Storage->NumFrames]),sizeof(short));
- ((short*)Storage->Buffer)[Storage->NumFrames - 1] = TargetValue;
- }
- break;
- }
- break;
- case eSampleStereo:
- switch (Storage->NumberOfBits)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "SetSampleStorageActualValue: bad internal num bits"));
- break;
- case eSample8bit:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "SetSampleStorageActualValue: bad channel selector"));
- break;
- case eLeftChannel:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
- if (TargetValue > MAX8BIT)
- {
- TargetValue = MAX8BIT;
- }
- else if (TargetValue < MIN8BIT)
- {
- TargetValue = MIN8BIT;
- }
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)[2 * Index]),
- sizeof(char));
- ((char*)Storage->Buffer)[2 * Index] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
- [2 * Storage->NumFrames]),sizeof(char));
- ((char*)Storage->Buffer)[2 * Storage->NumFrames] = TargetValue;
- }
- break;
- case eRightChannel:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX8BIT);
- if (TargetValue > MAX8BIT)
- {
- TargetValue = MAX8BIT;
- }
- else if (TargetValue < MIN8BIT)
- {
- TargetValue = MIN8BIT;
- }
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
- [(2 * Index) + 1]),sizeof(char));
- ((char*)Storage->Buffer)[(2 * Index) + 1] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((char*)Storage->Buffer)
- [(2 * Storage->NumFrames) + 1]),sizeof(char));
- ((char*)Storage->Buffer)[(2 * Storage->NumFrames) + 1]
- = TargetValue;
- }
- break;
- }
- break;
- case eSample16bit:
- switch (WhichChannel)
- {
- default:
- EXECUTE(PRERR(ForceAbort,
- "SetSampleStorageActualValue: bad channel selector"));
- break;
- case eLeftChannel:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
- if (TargetValue > MAX16BIT)
- {
- TargetValue = MAX16BIT;
- }
- else if (TargetValue < MIN16BIT)
- {
- TargetValue = MIN16BIT;
- }
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)[2 * Index]),
- sizeof(short));
- ((short*)Storage->Buffer)[2 * Index] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
- [2 * Storage->NumFrames]),sizeof(short));
- ((short*)Storage->Buffer)[2 * Storage->NumFrames]
- = TargetValue;
- }
- break;
- case eRightChannel:
- TargetValue = roundtonearest(largefixed2double(NewValue) * MAX16BIT);
- if (TargetValue > MAX16BIT)
- {
- TargetValue = MAX16BIT;
- }
- else if (TargetValue < MIN16BIT)
- {
- TargetValue = MIN16BIT;
- }
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
- [(2 * Index) + 1]),sizeof(short));
- ((short*)Storage->Buffer)[(2 * Index) + 1] = TargetValue;
- if (Index == Storage->NumFrames - 1)
- {
- PRNGCHK(Storage->Buffer,&(((short*)Storage->Buffer)
- [(2 * Storage->NumFrames) + 1]),sizeof(short));
- ((short*)Storage->Buffer)[(2 * Storage->NumFrames) + 1]
- = TargetValue;
- }
- break;
- }
- break;
- }
- break;
- }
- }
-
-
- /* get a reference to the raw data. The raw data will either be an array of chars */
- /* (for 8-bit data) or an array of shorts (for 16-bit data). There will be */
- /* GetSampleStorageActualNumFrames + 1 frames; the extra one at the end is to */
- /* make anti-aliasing more efficient, and repeats the second-last word of data */
- char* GetSampleStorageActualRawData(SampleStorageActualRec* Storage)
- {
- CheckPtrExistence(Storage);
- return Storage->Buffer;
- }
-
-
- /* get a copy of a particular channel of data from the sample */
- largefixedsigned* SampleStorageActualGetChannelFixed(
- SampleStorageActualRec* Storage, ChannelType WhichChannel)
- {
- largefixedsigned* Data;
- long Limit;
- long Scan;
-
- CheckPtrExistence(Storage);
- Limit = GetSampleStorageActualNumFrames(Storage);
- Data = (largefixedsigned*)AllocPtrCanFail(sizeof(largefixedsigned)
- * Limit,"SampleFixed");
- if (Data != NIL)
- {
- for (Scan = 0; Scan < Limit; Scan += 1)
- {
- Data[Scan] = GetSampleStorageActualValue(Storage,Scan,WhichChannel);
- }
- }
- return Data;
- }
-